/* 
 * File:   Servidor.cpp
 * Author: max
 * 
 * Created on October 19, 2012, 12:31 AM
 */

#include "server_Servidor.h"
#include "server_FileService.h"
using namespace TP::Comunicacion;

Servidor::Servidor(const string& pPuerto, const string &pRutaArchivoEncriptado, const int &pLongitudClave, const int &pCapacidadClientesMaxima ){
    
    this->conexion = new Conexion (pPuerto, this);
    this->_ecoService = new EcoService();
    this->log = &cerr;
}

Servidor::Servidor(const string& pPuerto, ostream *pLog, const string &pRutaArchivoEncriptado, const int &pLongitudClave, const int &pCapacidadClientesMaxima ){

    this->conexion = new Conexion (pPuerto, this);
    
    if (NULL == pLog)
        pLog = &cerr;
    
    this->log = pLog;

}

Servidor::~Servidor() {
    
    // Doy de baja la conexion.
    if (this->conexion)
        delete this->conexion;
    
}

void Servidor::Iniciar() throw (Excepcion&){
    try
    {
        this->conexion->Iniciar();
    }
    catch (Excepcion& pEx)
    {
        pEx.expandirMensaje("No se puede iniciar el sevidor.");
        throw;
    }
}

void Servidor::Finalizar() throw (Excepcion&){
    try
    {
        // Doy de baja la conexion a fin de evitar nuevas sesiones.
        this->conexion->Finalizar();
        
        // Doy de baja las sesiones activas.
        for (vector<Sesion*>::size_type cur = 0; cur < this->sesiones.size(); cur++)
        {
            try
            {
                this->sesiones[cur]->Finalizar();
            }
            catch (Excepcion& pEx)
            {
                *(this->log) << pEx.what() << endl;
            }
            delete this->sesiones[cur];
        }
        this->sesiones.clear();

    }
    catch (Excepcion& pEx)
    {
        pEx.expandirMensaje("No se puede finializar correctamente el sevidor.");
        throw;
    }
}

void Servidor::eventoNuevaSesion (IEnviante* pEnviante, void* pArg){
    
    Sesion* sesion = (Sesion*) pArg;
    
    try
    {
        if (sesion)
        {
            // Se configuran los manejadores de mensaje de la sesion.
            sesion->agregarManejadorSesionEvento(this);
            
            sesion->agregarMensajeEntranteManejador((IMensajeEntranteManejador*)this->_ecoService );
            
            // Se debe iniciar la escucha de mensajes de la sesion.
            sesion->Iniciar();
            
            // Se debe registrar la sesion en la lista de sesiones del servidor.
            this->sesiones.push_back(sesion);
        }
    }
    catch (Excepcion& pEx)
    {
        std::cout << "No se puede manejar la nueva sesion.  " << pEx.what() << endl;
    }
}

void Servidor::eventoErrorComunicacion (IEnviante* pEnviante, const string& pMensaje ){
    *(this->log) << pMensaje << endl;
}

void Servidor::eventoConexionFinalizada (IEnviante* pEnviante, const string& pMensaje){
    *(this->log) << pMensaje << endl;
}

void Servidor::eventoErrorConexionInexistente (IEnviante* pConexion, const string& pMensaje) {
    *(this->log) << pMensaje << endl;
}